package team.seekers.catering.food.service;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import team.seekers.catering.common.enums.DRIsEnum;
import team.seekers.catering.food.entity.dao.Food;
import team.seekers.catering.food.entity.pojo.*;
import team.seekers.catering.food.entity.vo.list.ComboListVO;
import team.seekers.catering.food.entity.dao.Combo;
import team.seekers.catering.food.entity.dto.update.ComboUpdateDTO;
import team.seekers.catering.food.entity.vo.info.ComboInfoVO;
import team.seekers.catering.food.entity.dto.add.ComboAddDTO;
import team.seekers.catering.food.mapper.ComboMapper;
import team.seekers.catering.user.entity.vo.info.EatLogAnalyzeInfoVO;
import team.seekers.catering.user.entity.vo.list.UserLogEatListVO;
import team.seekers.catering.user.service.UserService;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;


@Service
public class ComboService extends ServiceImpl<ComboMapper, Combo>{
    @Autowired
    private IngredientService ingredientService;

    @Autowired
    private UserService userService;

    @Autowired
    private FoodService foodService;

    public Map<String, Object> adminPageOrder(long current, long limit, QueryWrapper<Combo> wrapper) {
        Page<Combo> page = new Page<>(current,limit);
        wrapper.orderByDesc("gmt_create");
        page(page,wrapper);
        Long total = page.getTotal();
        if(page.getRecords() == null){
            return null;
        }

        List<ComboListVO> list = new ArrayList<>();
        for (Combo record : page.getRecords()) {
            ComboListVO vo = new ComboListVO();
            BeanUtils.copyProperties(record,vo);
            list.add(vo);
        }
        Map<String,Object> map = new HashMap<>();
        map.put("total",total);
        map.put("rows",list);
        return map;
    }

    public String add(ComboAddDTO comboAddDTO) {
        Combo aCombo = new Combo();
        BeanUtils.copyProperties(comboAddDTO, aCombo);

        List<ContainFoodListDTO> content1 = comboAddDTO.getContent();
        ArrayList<String> strings = new ArrayList<>();
        for (ContainFoodListDTO containFoodListDTO : content1) {
            strings.add(containFoodListDTO.getId());
        }
        String content = JSON.toJSONString(strings);
        aCombo.setFoodContent(content);

        String ingredientContent = JSON.toJSONString(comboAddDTO.getIngredientContent());
        aCombo.setIngredientContent(ingredientContent);

        String nd = JSON.toJSONString(comboAddDTO.getNrv());
        aCombo.setNrv(nd);

        List<ContainLabelListDTO> label1 = comboAddDTO.getLabel();
        ArrayList<ContainLabelListDO> containLabelListDOS = new ArrayList<>();
        for (ContainLabelListDTO containLabelListDTO : label1) {
            ContainLabelListDO containLabelListDO = new ContainLabelListDO();
            containLabelListDO.setName(containLabelListDTO.getName());
            containLabelListDO.setIsAlone(containLabelListDTO.getIsAlone());
            HashMap<String, Boolean> hashMap = new HashMap<>();
            for (String choose : containLabelListDTO.getChooses()) {
                hashMap.put(choose,false);
            }
            containLabelListDO.setChooses(hashMap);
            containLabelListDOS.add(containLabelListDO);
        }
        String label = JSON.toJSONString(containLabelListDOS);
        aCombo.setLabel(label);

        save(aCombo);
        return aCombo.getId();
    }

    public ComboInfoVO foodToVO(Combo combo){
        ComboInfoVO comboInfoVO = new ComboInfoVO();
        BeanUtils.copyProperties(combo, comboInfoVO);

        ArrayList<ContainNutrimentListVO> containNutrimentListVOS = new ArrayList<>();
        if(combo.getNrv() != null){
            List<ContainNutrimentListDO> containNutrimentListDOS = JSONObject.parseArray(combo.getNrv(), ContainNutrimentListDO.class);
            for (ContainNutrimentListDO containNutrimentListDO : containNutrimentListDOS) {
                containNutrimentListVOS.add(new ContainNutrimentListVO(
                        DRIsEnum.getByValue(containNutrimentListDO.getNutrimentId()).getName(),
                        containNutrimentListDO.getAmount()+" "+DRIsEnum.getByValue(containNutrimentListDO.getNutrimentId()).getUnit().split("/")[0],
                        new BigDecimal(containNutrimentListDO.getNutrimentContent()).multiply(new BigDecimal("100")).setScale(2,BigDecimal.ROUND_HALF_UP).toString()
                ));
            }
        }


        ArrayList<ContainIngredientListVO> containIngredientListVOS = new ArrayList<>();
        if(combo.getIngredientContent() != null){
            List<ContainIngredientListDTO> containIngredientListDTOS = JSONObject.parseArray(combo.getIngredientContent(), ContainIngredientListDTO.class);
            for (ContainIngredientListDTO containIngredientListDTO : containIngredientListDTOS) {
                containIngredientListVOS.add(new ContainIngredientListVO(
                        containIngredientListDTO.getId(),
                        ingredientService.getById(containIngredientListDTO.getId()).getNcName(),
                        containIngredientListDTO.getAmount()
                ));
            }
        }

        ArrayList<ContainFoodListVO> foodListPAS = new ArrayList<>();
        if(combo.getFoodContent() != null){
            List<String> containFoodIdList = JSONObject.parseArray(combo.getFoodContent(), String.class);
            for (String foodId : containFoodIdList) {
                Food food = foodService.getById(foodId);
                foodListPAS.add(new ContainFoodListVO(
                        food.getId(),
                        food.getName()
                ));
            }
        }

        comboInfoVO.setFoodContent(foodListPAS);

        List<ContainLabelListDO> label = JSONObject.parseArray(combo.getLabel(), ContainLabelListDO.class);
        comboInfoVO.setLabel(label);

        comboInfoVO.setNrv(containNutrimentListVOS);
        comboInfoVO.setIngredientList(containIngredientListVOS);
        return comboInfoVO;
    }

    public ComboInfoVO get(String id) {
        Combo aCombo = getById(id);
        return foodToVO(aCombo);
    }

    public String update(ComboUpdateDTO comboUpdateDTO) {
        Combo aCombo = new Combo();
        BeanUtils.copyProperties(comboUpdateDTO, aCombo);
        List<ContainFoodListDTO> content = comboUpdateDTO.getFoodContent();
        ArrayList<String> strings = new ArrayList<>();
        for (ContainFoodListDTO containFoodListDTO : content) {
            strings.add(containFoodListDTO.getId());
        }
        aCombo.setFoodContent(JSON.toJSONString(strings));
        aCombo.setNrv(JSON.toJSONString(comboUpdateDTO.getNrv()));
        aCombo.setLabel(JSON.toJSONString(comboUpdateDTO.getLabel()));
        updateById(aCombo);
        return aCombo.getId();
    }


    /**
     * 解析今日套餐组成，算出套餐成分
     * @param eatLogAnalyzeInfoVO
     */
    public EatLogAnalyzeInfoVO setParamFromList(EatLogAnalyzeInfoVO eatLogAnalyzeInfoVO) {
        // 统计食材
        ArrayList<ContainIngredientListDTO> ingredientList = new ArrayList<>();
        for (UserLogEatListVO userLogEatListVO : eatLogAnalyzeInfoVO.getEatLogVOList()) {
            ComboInfoVO combo = get(userLogEatListVO.getComboId());
            userLogEatListVO.setComboName(combo.getName());
            userLogEatListVO.setEnergy(combo.getKal());
            for (ContainFoodListVO containFoodListVO : combo.getFoodContent()) {
                Food food = foodService.getById(containFoodListVO.getId());
                List<ContainIngredientListDTO> containIngredientListDTOS = JSONObject.parseArray(food.getIngredientContent(), ContainIngredientListDTO.class);
                for (ContainIngredientListDTO containIngredientListDTO : containIngredientListDTOS) {
                    boolean isExit = false;
                    for (ContainIngredientListDTO listPA : ingredientList) {
                        if(listPA.getId() == containIngredientListDTO.getId()){
                            isExit = true;
                            listPA.setAmount(listPA.getAmount()+ containIngredientListDTO.getAmount());
                        }
                    }
                    if(!isExit){
                        ingredientList.add(containIngredientListDTO);
                    }
                }
            }
        }

        eatLogAnalyzeInfoVO.setIngredientContent(ingredientList);
        ingredientService.setVOFromList(eatLogAnalyzeInfoVO);
        return eatLogAnalyzeInfoVO;
    }

    /**
     * 解析套餐组成
     */
    public ComboUpdateDTO setParamFromList(ComboUpdateDTO comboUpdateDTO) {
        // 统计食材
        ArrayList<ContainIngredientListDTO> ingredientList = new ArrayList<>();
        for (ContainFoodListDTO containFoodListDTO : comboUpdateDTO.getFoodContent()) {
            Food food = foodService.getById(containFoodListDTO.getId());
            List<ContainIngredientListDTO> containIngredientListDTOS = JSONObject.parseArray(food.getIngredientContent(), ContainIngredientListDTO.class);
            for (ContainIngredientListDTO containIngredientListDTO : containIngredientListDTOS) {
                boolean isExit = false;
                for (ContainIngredientListDTO listPA : ingredientList) {
                    if(listPA.getId() == containIngredientListDTO.getId()){
                        isExit = true;
                        listPA.setAmount(listPA.getAmount()+ containIngredientListDTO.getAmount());
                    }
                }
                if(!isExit){
                    ingredientList.add(containIngredientListDTO);
                }
            }
        }
        comboUpdateDTO.setIngredientContent(ingredientList);
        ingredientService.setParamFromList(comboUpdateDTO);
        return comboUpdateDTO;
    }
}
